package com.hksj.umm.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hksj.common.core.util.DateUtil;
import com.hksj.umm.mapper.UVDeviceMapper;
import com.hksj.umm.query.UVDeviceRecordCountQuery;
import com.hksj.umm.query.UVDeviceRecordQuery;
import com.hksj.umm.vo.UVDeviceRecordCountVO;
import com.hksj.umm.vo.UVDeviceRecordVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class UVDeviceService {

    @Autowired
    private UVDeviceMapper uVDeviceMapper;

    /**
     * 查询紫外设备工作记录
     *
     * 本方法通过接收查询参数，分页查询紫外设备的工作记录，并返回分页结果
     *
     * @param query 包含查询条件和分页信息的查询对象
     * @return 返回一个分页对象，包含查询到的紫外设备工作记录
     */
    public IPage<UVDeviceRecordVO> queryUVDeviceWorkRecord(UVDeviceRecordQuery query)  {
        // 创建分页对象，初始化页码和页面大小
        IPage<UVDeviceRecordVO> page = new Page<>(query.getPageNum(), query.getPageSize());

        // 调用mapper层方法，执行查询，并将结果设置到分页对象中
        List<UVDeviceRecordVO> list = uVDeviceMapper.queryUVDeviceWorkRecord(page, query);
        list.forEach(item -> {
                if (!ObjectUtils.isEmpty(item.getOpenTime()) && !ObjectUtils.isEmpty(item.getCloseTime())){
                    // 计算照明时长，单位：小时
                    long milliseconds = item.getCloseTime().getTime() - item.getOpenTime().getTime();
                    // 将毫秒转换为分钟，保留两位小数
                    BigDecimal hours = new BigDecimal(milliseconds).divide(new BigDecimal(1000 * 60 ), 2, RoundingMode.HALF_UP);
                    // 设置照明时长
                    item.setTotalTime(hours);
                }
                });
        page.setRecords(list);

        // 返回填充了查询结果的分页对象
        return page;
    }


    /**
     * 查询UV设备工作计数
     * 根据查询参数获取UV设备的工作计数信息，包括设备的总时间和总次数
     *
     * @param query 查询参数，包含页码、页面大小、开始时间和结束时间等信息
     * @return 返回一个分页对象，包含UV设备工作计数的列表
     */
    public IPage<UVDeviceRecordCountVO> queryUVDeviceWorkCount(UVDeviceRecordCountQuery query) {
        // 创建分页对象
        IPage<UVDeviceRecordCountVO> page = new Page<>(query.getPageNum(), query.getPageSize());

        // 查询UV设备工作计数概述信息
        List<UVDeviceRecordCountVO> list = uVDeviceMapper.queryUVDeviceWorkCount(page, query);
        // 查询UV设备工作计数详细信息
        List<UVDeviceRecordCountVO> listDetail = uVDeviceMapper.queryUVDeviceWorkCountDetail(query);

        if (!CollectionUtils.isEmpty(listDetail)) {
            // 对每个详细信息项进行处理，计算照明小时数
            listDetail.forEach(item -> {
                checkLightingHour(item, query.getStartTime(), query.getEndTime());
            });

            // 将详细信息列表转换为字典，以便后续查询
            Map<String, List<UVDeviceRecordCountVO>> map = listDetail.stream().collect(Collectors.groupingBy(p -> p.getDeviceId() + "-" + p.getProperty()));

            // 对每个概述信息项进行处理，计算总时间和总次数
            list.forEach(item -> {
                List<UVDeviceRecordCountVO> detailList = map.get(item.getDeviceId() + "-" + item.getProperty());
                if(!CollectionUtils.isEmpty(detailList)) {
                    // 提取 totalTime 字段，并计算总和
                    item.setTotalTime(detailList.stream()
                            .map(UVDeviceRecordCountVO::getTotalTime)
                            .filter(Objects::nonNull)
                            .reduce(BigDecimal.ZERO, BigDecimal::add));
                    // 设置总次数
                    item.setTotalCount(detailList.size());
                }
            });
        }

        // 设置分页对象的记录列表
        page.setRecords(list);

        // 返回分页对象
        return page;
    }

    /**
     * 检查并计算设备的照明小时数
     * 此方法根据设备的开启和关闭时间以及查询的时间范围来计算照明时长
     *
     * @param uvDeviceRecordCountVO 包含设备信息和开启关闭时间的对象
     * @param queryStartTime 查询开始时间
     * @param queryEndTime 查询结束时间
     */
    private void checkLightingHour(UVDeviceRecordCountVO uvDeviceRecordCountVO, Date queryStartTime, Date queryEndTime) {
        // 初始化开始时间为null，后续将根据条件赋值
        Date startTime = null;
        // 获取设备的开启时间
        Date openTime = uvDeviceRecordCountVO.getOpenTime();
        // 获取设备的关闭时间
        Date closeTime = uvDeviceRecordCountVO.getCloseTime();

        // 判断查询起始时间是否晚于设备开启时间，是则使用查询起始时间，否则使用设备开启时间
        if (queryStartTime.compareTo(openTime) > 0){
            // 查询起始时间晚于openTime
            startTime = queryStartTime;
        }else {
            startTime = openTime;
        }

        // 初始化结束时间为null，后续将根据条件赋值
        Date endTime = null;
        // 获取当前系统时间
        Date currentTime = new Date();
        // 判断查询截止时间是否晚于设备关闭时间，是则使用设备关闭时间，否则使用查询截止时间
        if (ObjectUtils.isEmpty(closeTime)) {
            // 如果 closeTime 为空，使用当前时间和 queryEndTime 的较小值
            endTime = (currentTime.compareTo(queryEndTime) > 0) ? queryEndTime : currentTime;
        } else {
            // 如果 closeTime 不为空，比较 closeTime 和 queryEndTime
            endTime = (queryEndTime.compareTo(closeTime) > 0) ? closeTime : queryEndTime;
        }

        // 计算照明时长，单位：小时
        long milliseconds = endTime.getTime() - startTime.getTime();
        // 将毫秒转换为小时，保留两位小数
        BigDecimal hours = new BigDecimal(milliseconds).divide(new BigDecimal(1000 * 60 * 60), 2, RoundingMode.HALF_UP);

        // 将计算得到的照明时长设置到设备信息对象中
        uvDeviceRecordCountVO.setTotalTime(hours);
    }


}
